﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

using MillsClient;

namespace MillsClientGameForm
{
    public partial class MillsClientForm : Form
    {
        //Объект клиента
        AsynchronoiusIOClient _millsClientObj;
        //Список фишек на поле и список точек, на кот можно размещать фишки.
        List<Chip> _chipsOnField = new List<Chip>();
        List<Point> AvalaiblePoints;
        //Объект игровой фишки и её изображения.
        bool _leading; 
        PictureBox _chipPic = new PictureBox();
        ChipColor _playColor;
        ChipColor _opponColor;
        //Бефферы для приема и отправки сообщений.
        string _sendBuffer = string.Empty;
        string _recBuffer = string.Empty;

        string WhiteChipImage = @"D:\U4eba\IX\TISIIS\Mills\Mills\ChipsWhite.png";
        string BlackChipImage = @"D:\U4eba\IX\TISIIS\Mills\Mills\ChipsWhite.png";
        string SelectedChipImage =  @"D:\U4eba\IX\TISIIS\Mills\Mills\ChipsWhite.png";

        GameState state;
        #region //Инициализация формы
        public MillsClientForm()
        {
            InitializeComponent();
        }
        public MillsClientForm(ref AsynchronoiusIOClient client, bool leading, string name, string opponent)
        {
            InitializeComponent();
            _leading = leading;
            _millsClientObj = client;  

            AvalaiblePoints = new List<Point>();
            AvalaiblePoints = GetPalyingFieldsPoints();

            switch (_leading)
            {
                case true:
                    state = GameState.now;
                    lbColorPlayer.Text = "Белые фишки";
                    lbColorOpponent.Text = "Черные фишки";
                    _playColor = ChipColor.white;
                    _opponColor = ChipColor.black;
                    break;
                case false:
                    state = GameState.wait;
                    lbColorPlayer.Text = "Черные фишки";
                    lbColorOpponent.Text = "Белые фишки";
                    _playColor = ChipColor.black;
                    _opponColor = ChipColor.white;
                    break;
            }

            ChkLeading(_leading);

            gbPlayer.Text += "  " + name;
            gbEnemy.Text += "  " + opponent;

            if (_playColor == ChipColor.white)
                _chipPic.ImageLocation = WhiteChipImage;
            else
                _chipPic.ImageLocation = BlackChipImage;
        }
        #endregion

        private void ChkLeading(bool leading)
        {
            if (leading)
                this.pbField.Enabled = true;
            else
                this.pbField.Enabled = false;
        }

        private enum GameState
        { now, wait }
        
        private void pbField_MouseClick(object sender, MouseEventArgs e)
        {
            Point pt = GetChoords(e.X, e.Y, ref pbField);
            MessageBox.Show("Click!");
            ChipsMovementOnField(pt);
        }

        //Действие с фишками на поле.
        private void ChipsMovementOnField(Point pt)
        {
            MessageBox.Show("0");
            if (AvalaiblePoints.Contains(pt))
            {
                MessageBox.Show("1");
                if (_chipsOnField.Count > 1)
                {
                    foreach (Chip chp in _chipsOnField)
                    {
                        MessageBox.Show("2");
                        if (chp.X == pt.X && chp.Y == pt.Y && chp.Color == _playColor)
                        {
                            _sendBuffer = string.Format(@"take=({0},{1})\EOM", chp.X, chp.Y);//@"take=(" + chp.X + "," + chp.Y + @")\EOM";
                        }
                        if (chp.X == pt.X && chp.Y == pt.Y && chp.Color != _playColor)
                        {
                            _sendBuffer = string.Format(@"remove=({0},{1})\EOM", chp.X, chp.Y); //@"remove=(" + chp.X + "," + chp.Y + @")\EOM";
                        }
                        else
                            _sendBuffer = string.Format(@"move=({0},{1})\EOM", chp.X, chp.Y); //@"move=(" + chp.X + "," + chp.Y + @")\EOM";
                    }
                }
                else
                {
                    _sendBuffer = string.Format(@"place=({0},{1})\EOM", pt.X, pt.Y);
                }
                _millsClientObj.Send(_sendBuffer);
                Logger.WriteLog("Sent: " + _sendBuffer);
            }
        }

        //public void AddToField(int x, int y)
        //{
        //    PictureBox addingChip = new PictureBox();
        //    addingChip.Size = new Size(pbField.Size.Width / 8, pbField.Size.Width / 8);

        //    int dX = (pbField.Size.Width / 7 * (_chip.X - 1));
        //    int dy = (pbField.Size.Height / 7 * (_chip.Y - 1));

        //    addingChip.SizeMode = PictureBoxSizeMode.StretchImage;
        //    addingChip.Location = new Point(dX, dy);
        //    addingChip.ImageLocation = _chipPic.ImageLocation;
        //    addingChip.MouseClick += addingChip_MouseClick;
        //    addingChip.Name = _chip.X.ToString() + _chip.Y.ToString();
        //    pbField.Controls.Add(addingChip);
        //}

        public void AddToField(Point pt, ChipColor col)
        {
            PictureBox addingChipPic = new PictureBox();
            Chip addingChip = new Chip();
            addingChipPic.Size = new Size(pbField.Size.Width / 8, pbField.Size.Width / 8);

            int dX = (pbField.Size.Width / 7 * (pt.X - 1));
            int dy = (pbField.Size.Height / 7 * (pt.Y - 1));

            addingChipPic.SizeMode = PictureBoxSizeMode.StretchImage;
            addingChipPic.Location = new Point(dX, dy);
            addingChipPic.ImageLocation = _chipPic.ImageLocation;
            addingChipPic.MouseClick += addingChip_MouseClick;
            addingChipPic.Name = pt.X.ToString() + pt.Y.ToString();
            pbField.Controls.Add(addingChipPic);

            addingChip.Name = pt.X.ToString() + pt.Y.ToString();
            addingChip.X = pt.X;
            addingChip.Y = pt.Y;
            addingChip.Color = col;
            _chipsOnField.Add(addingChip);
        }

        void addingChip_MouseClick(object sender, MouseEventArgs e)
        {
            PictureBox pb = (PictureBox)sender;
            bool flag = true;
            if (!flag)
            {
                pb.Parent.Controls.RemoveByKey(pb.Name);
            }
            else
                pb.ImageLocation = @"D:\U4eba\IX\TISIIS\Mills\Mills\ChipsSelected.png";
        }


        void RecieveMesages()
        {
            Point newPlace = new Point();
            Point Place = new Point();
            string bufferR = string.Empty;
            PictureBox tmp;
            Chip tmpChip = new Chip();
            string buffer = string.Empty;

            while (true)
            {
                //_recBuffer = _millsClientObj.Recieve();
                bufferR = _recBuffer.Substring(0, (_recBuffer.IndexOf('=')));
                switch (bufferR)
                { 
                    case @"success\EOM":
                        if (buffer != _recBuffer)
                        {
                            string bufferS = _sendBuffer.Substring(0, (_recBuffer.IndexOf('=')));
                            switch (bufferS)
                            {
                                case "place=":
                                    Place = GetCoordsFromMsg(_sendBuffer);
                                    AddToField(Place, _playColor);
                                    _recBuffer = string.Empty;
                                    _sendBuffer = string.Empty;
                                    break;
                                case "take=":
                                    Place = GetCoordsFromMsg(_sendBuffer);
                                    tmp = (PictureBox)pbField.Controls[Place.X.ToString() + Place.Y.ToString()];
                                    tmp.ImageLocation = SelectedChipImage;

                                    _recBuffer = string.Empty;
                                    _sendBuffer = string.Empty;
                                    break;
                                case "move=":
                                    newPlace = GetCoordsFromMsg(_sendBuffer);
                                    tmp = (PictureBox)pbField.Controls[Place.X.ToString() + Place.Y.ToString()];
                                    tmp.Location = newPlace;
                                    if (_playColor == ChipColor.black)
                                        tmp.ImageLocation = BlackChipImage;
                                    else
                                        tmp.ImageLocation = WhiteChipImage;
                                    Place = newPlace;

                                    _recBuffer = string.Empty;
                                    _sendBuffer = string.Empty;
                                    break;
                                case "remove=":
                                    Place = GetCoordsFromMsg(_sendBuffer);
                                    pbField.Controls.RemoveByKey(Place.X.ToString() + Place.Y.ToString());
                                    tmpChip.Name = Place.X.ToString() + Place.Y.ToString();
                                    foreach (Chip chip in _chipsOnField)
                                    {
                                        if (chip.Name == Place.X.ToString() + Place.Y.ToString() && chip.Color == _playColor)
                                            _chipsOnField.Remove(chip);
                                    }
                                    _recBuffer = string.Empty;
                                    _sendBuffer = string.Empty;
                                    break;
                                default:
                                    break;
                            }
                            buffer = _recBuffer;
                        }
                        break;
                    case @"denied\EOM":
                        break;
                    case @"sync take=":
                        if (buffer != _recBuffer)
                        {
                            Place = GetCoordsFromMsg(_recBuffer);
                            tmp = (PictureBox)pbField.Controls[Place.X.ToString() + Place.Y.ToString()];
                            tmp.ImageLocation = SelectedChipImage;

                            _recBuffer = string.Empty;
                            buffer = _recBuffer;
                        }
                        break;
                    case @"synk move=":
                        if (buffer != _recBuffer)
                        {
                            newPlace = GetCoordsFromMsg(_recBuffer);
                            tmp = (PictureBox)pbField.Controls[Place.X.ToString() + Place.Y.ToString()];
                            tmp.Location = newPlace;
                            if (_playColor == ChipColor.black)
                                tmp.ImageLocation = BlackChipImage;
                            else
                                tmp.ImageLocation = WhiteChipImage;
                            Place = newPlace;

                            _recBuffer = string.Empty;
                            buffer = _recBuffer;
                        }
                        break;
                    case @"synk place=":
                        if (buffer != _recBuffer)
                        {
                            Place = GetCoordsFromMsg(_recBuffer);
                            AddToField(Place, _opponColor);
                            buffer = _recBuffer;
                        }
                        break;
                    case @"sync remove=":
                        if (buffer != _recBuffer)
                        {
                            Place = GetCoordsFromMsg(_recBuffer);
                            pbField.Controls.RemoveByKey(Place.X.ToString() + Place.Y.ToString());
                            tmpChip.Name = Place.X.ToString() + Place.Y.ToString();
                            foreach (Chip chip in _chipsOnField)
                            {
                                if (chip.Name == Place.X.ToString() + Place.Y.ToString() && chip.Color == _playColor)
                                    _chipsOnField.Remove(chip);
                            }
                            _recBuffer = string.Empty;
                            buffer = _recBuffer;
                        }
                        break;
                    case @"change lead\EOM":
                        if (state == GameState.now)
                        {
                            this.Enabled = false;
                            state = GameState.wait;
                        }
                        else
                        { this.Enabled = true; state = GameState.now; }
                        break;
                    case @"end win=\EOM":
                        if (buffer != _recBuffer)
                        {
                            if (_recBuffer.Contains("Yes"))
                                MessageBox.Show("Bravo! You win!");
                            else
                                MessageBox.Show("You lose((");

                            buffer = _recBuffer;
                        }
                        break;
                    case @"error=\EOM":
                        if (buffer != _recBuffer)
                        {
                            this.lbError.Text = _recBuffer;
                            buffer = _recBuffer;
                        }
                        break;
                    default:
                        break;
                }
            }
        }

        private Point GetCoordsFromMsg(string msg)
        {
            Point pt = new Point();
            string tmp = msg.Substring(msg.IndexOf('('));
            int X = int.Parse(tmp.Substring(1, 1));
            int Y = int.Parse(tmp.Substring(3, 1));

            pt.X = X;
            pt.Y = Y;

            return pt;
        }

        #region Field
        private List<Point> GetPalyingFieldsPoints()
        {
            List<Point> ptList = new List<Point>();
            Point pt = new Point();
            //1st row
            pt.X = 1; pt.Y = 1;
            ptList.Add(pt);

            pt.X = 1; pt.Y = 4;
            ptList.Add(pt);

            pt.X = 1; pt.Y = 7;
            ptList.Add(pt);
            //2d row
            pt.X = 2; pt.Y = 2;
            ptList.Add(pt);

            pt.X = 2; pt.Y = 4;
            ptList.Add(pt);

            pt.X = 2; pt.Y = 6;
            ptList.Add(pt);
            //3d row
            pt.X = 3; pt.Y = 3;
            ptList.Add(pt);

            pt.X = 3; pt.Y = 4;
            ptList.Add(pt);

            pt.X = 3; pt.Y = 5;
            ptList.Add(pt);
            //4th row
            pt.X = 4; pt.Y = 1;
            ptList.Add(pt);

            pt.X = 4; pt.Y = 2;
            ptList.Add(pt);

            pt.X = 4; pt.Y = 3;
            ptList.Add(pt);

            pt.X = 4; pt.Y = 5;
            ptList.Add(pt);

            pt.X = 4; pt.Y = 6;
            ptList.Add(pt);

            pt.X = 4; pt.Y = 7;
            ptList.Add(pt);
            //5th row
            pt.X = 5; pt.Y = 3;
            ptList.Add(pt);

            pt.X = 5; pt.Y = 4;
            ptList.Add(pt);

            pt.X = 5; pt.Y = 5;
            ptList.Add(pt);
            //6th row
            pt.X = 6; pt.Y = 2;
            ptList.Add(pt);

            pt.X = 6; pt.Y = 4;
            ptList.Add(pt);

            pt.X = 6; pt.Y = 6;
            ptList.Add(pt);
            //7th row
            pt.X = 7; pt.Y = 1;
            ptList.Add(pt);

            pt.X = 7; pt.Y = 4;
            ptList.Add(pt);

            pt.X = 7; pt.Y = 7;
            ptList.Add(pt);
            return ptList;
        }

        private Point GetChoords(int X, int Y, ref PictureBox pb)
        {
            Point ptCoord = new Point();
            int dX = pb.Size.Height / 7;
            int dY = pb.Size.Width / 7;

            int i = 0;

            while (i * dX < X)
            {
                i++;
            }
            ptCoord.X = i;

            i = 0;
            while (i * dY < Y)
            {
                i++;
            }
            ptCoord.Y = i;

            return ptCoord;
        }
        #endregion

        private Chip ChipPlace(int X, int Y, ref PictureBox pb)
        {
            Chip dot = new Chip();
            double dX = pb.Size.Height / 7;
            double dY = pb.Size.Width / 7;

            int i = 0;

            while (i * dX < X)
            {
                i++;
            }
            dot.X = i;

            i = 0;
            while (i * dY < Y)
            {
                i++;
            }
            dot.Y = i;

            dot.Name = dot.X.ToString() + dot.Y.ToString();

            return dot;
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void MillsClientForm_Load(object sender, EventArgs e)
        {
            //if (_playColor == ChipColor.white)
            //    _chipPic.ImageLocation = WhiteChipImage;
            //else
            //    _chipPic.ImageLocation = BlackChipImage;
            //AvalaiblePoints = new List<Point>();
            //AvalaiblePoints = GetPalyingFieldsPoints();
            MessageBox.Show("FormLoaded");
        }
    }

    public enum ChipColor
    { white, black, selected}

    public class Chip
    {
        string _name;
        int _Xcoord;
        int _YCoord;
        ChipColor _color;

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public int X
        {
            get { return _Xcoord; }
            set { _Xcoord = value; }
        }
        public int Y
        {
            get { return _YCoord; }
            set { _YCoord = value; }
        }
        public ChipColor Color
        {
            get { return _color; }
            set { _color = value; }
        }
        public Chip(int X, int Y, ChipColor col)
        {
            _Xcoord = X;
            _YCoord = Y;
            _name = X.ToString() + Y.ToString();
            _color = col;
        }

        public Chip()
        {
            _YCoord = -1;
            _Xcoord = -1;
            _name = X.ToString() + Y.ToString();
            _color = ChipColor.white;
        }
    }
}